/******************************************************
* Team WB
* Brett Cate, William Kim
* 
* Debug Monitor ADT Header
*******************************************************/

#ifndef SC2_H
#include "sc2.h"
#endif


#ifndef DEBUGMONITOR_H
#define DEBUGMONITOR_H

#include <ncurses.h>
#ifndef CPU_H
#include "cpu.h"
#endif

CPUPtr cpu_ptr;

/*
Contains debug state, breakpoint addresses, and a pointer to the CPU.
*/
typedef struct debugMonitor {
	int     debugState;		// used to inform the CPU
	ushort*	breakPoints;
	int breakpoint_index;
	ushort	currentPCValue;
	ushort	memDumpStart;
	CPUPtr cpu_ptr;
} DebugMonitor;

typedef DebugMonitor* DebugMonitorPtr;



/*
ADT - DebugMonitor
	Data Type Description:
	Contains debug state and breakpoint addresses. Note you need not implement the latter in this phase
		int     debugState;		// used to inform the CPU
		ushort	breakPoints[MAXBREAKPOINTS];
		ushort	currentPCValue;
		ushort	memDumpStart;

	Operations:
		Initialize		// new a debug monitor and initialize the above variables
		LoadProgram		// open a text file containing a loadable program and read that text into
						// main memory starting at the load address given in the first line of the
						// file (use the same format as the LC-3 load file)
		RunProgram		// sets cpu->PC to 0x3000, start of user program; sets debugState to RUN
		StepProgram		// sets cpu->PC to 0x3000, sets debugState to STEP
		ShowRegisters	// refreshes register contents; returns to cpu_run()
		ShowMemory		// gets start address to dump and shows 16 words of memory in following format:
						// address	byte  byte
						// x3400    2A    01
						//           ^     ^
						//           |     +-- byte at x3401
						//           +-------- byte at x3400
		ShowAll			// refreshes all screen variables

		appropriate getters and setters
*/

/*
Constructs a new debug monitor and initializes its fields.

return value : A pointer to the new debug monitor object.
*/
DebugMonitorPtr debugMonitor_new(CPUPtr the_cpu, int* the_error);

/*
Opens a text file containing a loadable program and reads that text into
main memory starting at the load address given in the first line of the file

parameter (the_debug_monitor_ptr): the debug monitor object.
parameter (the_file_name): The name of the file to load.

return value: Error code.
*/
int debugMonitor_loadProgram(DebugMonitorPtr the_debug_monitor_ptr, char* the_file_name);

/*
Sets cpu->PC to 0x3000, start of user program; sets debugState to RUN.

parameter (the_debug_monitor_ptr): the debug monitor object.

return value: Error code.
*/
int debugMonitor_runProgram(DebugMonitorPtr the_debug_monitor_ptr);

/*
Sets cpu->PC to 0x3000, sets debugState to STEP.

parameter (the_debug_monitor_ptr): the debug monitor object.

return value: Error code.
*/
int debugMonitor_stepProgram(DebugMonitorPtr the_debug_monitor_ptr);

/*
Prompts for and adds a breakpoint to this debug monitor.
*/
void debugMonitor_addBreakpoint(DebugMonitorPtr the_debug_monitor_ptr);

/*
Refreshes register contents; returns to cpu_run().

parameter (the_debug_monitor_ptr): the debug monitor object.

return value: Window for the registers.
*/
WINDOW* debugMonitor_showRegisters(DebugMonitorPtr the_debug_monitor_ptr);

/*
Gets start address to dump and shows 16 words of memory in following format:
						address	byte  byte
						x3400    2A    01
						          ^     ^
						          |     +-- byte at x3401
						          +-------- byte at x3400

parameter (the_debug_monitor_ptr): the debug monitor object.

return value: Window for the memory.
*/
WINDOW* debugMonitor_showMemory(DebugMonitorPtr the_debug_monitor_ptr);

/*
Refreshes all screen variables.

parameter (the_debug_monitor_ptr): the debug monitor object.

return value: Master window for the cpu.
*/
WINDOW* debugMonitor_showAll(DebugMonitorPtr the_debug_monitor_ptr);

/*
parameter (the_debug_monitor_ptr): the debug monitor object.
parameter (the_error) : the error code.

return value: the debug state of this debug monitor.
*/
int debugMonitor_getDebugState(DebugMonitorPtr the_debug_monitor_ptr, int* the_error);

/*
Sets the debug state.

parameter (the_debug_monitor_ptr): the debug monitor object.

return value: Error code.
*/
int debugMonitor_setDebugState(DebugMonitorPtr the_debug_monitor_ptr, int the_debug_state);

/*
parameter (the_debug_monitor_ptr): the debug monitor object.
parameter (the_error) : the error code.

return value: the array of break points of this debug monitor.
*/
ushort* debugMonitor_getBreakPoints(DebugMonitorPtr the_debug_monitor_ptr, int* the_error);

/*
Sets the break points. 

parameter (the_debug_monitor_ptr): the debug monitor object.

return value: Error code.
*/
int debugMonitor_setBreakPoints(DebugMonitorPtr the_debug_monitor_ptr, ushort* the_break_points);

/*
parameter (the_debug_monitor_ptr): the debug monitor object.
parameter (the_error) : the error code.

return value: the current PC value.
*/
ushort debugMonitor_getCurrentPCValue(DebugMonitorPtr the_debug_monitor_ptr, int* the_error);

/*
Sets the current PC value.

parameter (the_debug_monitor_ptr): the debug monitor object.

return value: Error code.
*/
int debugMonitor_setCurrentPCValue(DebugMonitorPtr the_debug_monitor_ptr, ushort the_PC_value);

/*
parameter (the_debug_monitor_ptr): the debug monitor object.
parameter (the_error) : the error code.

return value: the the memory dump start location.
*/
ushort debugMonitor_getMemDumpStart(DebugMonitorPtr the_debug_monitor_ptr, int* the_error);

/*
Sets the memory dump start location.

parameter (the_debug_monitor_ptr): the debug monitor object.

return value: Error code.
*/
int debugMonitor_setMemDumpStart(DebugMonitorPtr the_debug_monitor_ptr, ushort the_mem_dump_start);

#endif
